<?php
/**
 * Created by PhpStorm.
 * User: dell
 * Date: 2018/1/27
 * Time: 12:31
 */

namespace app\cls\tom;


class Process
{
    private $php_script_filename;//进程执行的脚本文件

    private $processNum = 1;//允许最大的进程数
    private $script_run_time = 300;//进程最大允许时间
    private static $logPath = "/data0/logs/host";//进程日志输出目录
    private $redirect_output = "/dev/null";//进程标准输出重定向
    private $script_start_time;//进程开始时间
    public $isTryError = true;


    public function __construct($phpScriptFile = "")
    {
        if($phpScriptFile){
            $this->php_script_filename = $phpScriptFile;
        }
        $this->script_start_time = time();
    }

    public function initProcess()
    {
        if(php_sapi_name() != 'cli'){
            exit("the process only work in cli mode! ");
        }
        if($this->processNum == 1){
            sleep(1);//休眠一秒 保证父进程 及时退出
        }
        $num = static::checkProcessNum($this->php_script_filename);
        if($num > $this->processNum){
            exit(0);
        }
        if(!file_exists(self::$logPath)){
            mkdir(self::$logPath,0777,true);
        }
        //设置异常处理
        //设置错误处理
        if($this->isTryError){
            set_error_handler(array($this,"errorHandel"));
        }
    }
    public function checkProcessTime($isRestart = true){
        if($this->script_start_time + $this->script_run_time <= time()){
            if($isRestart){
                $this->restartProcess();
            }
        }
    }
    public  function restartProcess()
    {
        $command = "/usr/bin/nohup /app/php/bin/php {$this->php_script_filename} > {$this->redirect_output} 2>&1 &";
        exec($command);
        exit;
    }

    //记录日志
    public function log($msg){
        $logFileName = basename($this->php_script_filename,".php").".log";
        $logPath = rtrim(self::$logPath,"/")."/".$logFileName;
        file_put_contents($logPath,$msg."\n",FILE_APPEND|LOCK_EX);
    }
    public static function startOtherScriptProcess($script_file_name,$param = ""){
        if(is_array($param)){
            $param = implode(" ",$param);
        }
        $command = "/usr/bin/nohup /app/php/bin/php {$script_file_name} {$param}> /dev/null 2>&1 &";
        exec($command);
    }
    public static function getCommandOutput($command)
    {
        ob_start();
        passthru($command." 2>&1");
        return ob_get_clean();
    }
    public static function checkProcessNum($script_file_name){
        $num = exec("ps -ef | grep ".$script_file_name." | grep -v grep | grep -v '/bin/sh' |wc -l");
        return $num;
    }

    //加入异常处理
    public  function exceptionHandel(){
        
    }
    //加入日志处理
    public function errorHandel($errNo ,$errStr,$errorFile='',$errLine = NULL,$errContext=NULL){
        $file = rtrim(self::$logPath,"/")."/"."tom_cron_error.log";
        file_put_contents($file,date("Y-m-d H:i:s ").$errorFile."===".$errStr."==错误行{$errLine}\n",FILE_APPEND|LOCK_EX);
        return true;
    }
    /**
     * @return int
     */
    public function getProcessNum()
    {
        return $this->processNum;
    }

    /**
     * @param string $logPath
     */
    public function setLogPath($logPath)
    {
        $this->logPath = $logPath;
    }

    /**
     * @param int $processNum
     */
    public function setProcessNum($processNum)
    {
        $this->processNum = $processNum;
    }

    /**
     * @return string
     */
    public function getPhpScriptFilename()
    {
        return $this->php_script_filename;
    }

    /**
     * @return int
     */
    public function getScriptRunTime()
    {
        return $this->script_run_time;
    }

    /**
     * @param int $script_run_time
     */
    public function setScriptRunTime($script_run_time)
    {
        $this->script_run_time = $script_run_time;
    }

    /**
     * @param string $php_script_filename
     */
    public function setPhpScriptFilename($php_script_filename)
    {
        $this->php_script_filename = $php_script_filename;
    }


}